/**
 * forEach
 */

Array.prototype.myForEach = function (cb) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this,bindThis = arguments[1] || window
  for (let i = 0; i < _arr.length; i++) {
    cb.call(bindThis,_arr[i],i,_arr)
  }
}

Array.prototype.myMap = function (cb) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this,bindThis = arguments[1] || window,res=[]
  for (let i = 0; i < _arr.length; i++) {
    const r = cb.call(bindThis,_arr[i],i,_arr)
    res.push(r)
  }
  return res
}


Array.prototype.myFilter = function (cb) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this,bindThis = arguments[1] || window,res=[]
  for (let i = 0; i < _arr.length; i++) {
    const r = cb.call(bindThis,_arr[i],i,_arr)
    if (!!r) {
      res.push(_arr[i])
    }
  }
  return res
}

Array.prototype.myEvery = function (cb) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this,bindThis = arguments[1] || window
  for (let i = 0; i < _arr.length; i++) {
    const r = cb.call(bindThis,_arr[i],i,_arr)
    if (!r) {
      return false
    }
  }
  return true
}

Array.prototype.mySome = function (cb) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this,bindThis = arguments[1] || window
  for (let i = 0; i < _arr.length; i++) {
    const r = cb.call(bindThis,_arr[i],i,_arr)
    if (r) {
      return true
    }
  }
  return false
}

Array.prototype.myFind = function (cb) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this,bindThis = arguments[1] || window
  for (let i = 0; i < _arr.length; i++) {
    const r = cb.call(bindThis,_arr[i],i,_arr)
    if (r) {
      return _arr[i]
    }
  }
  return undefined
}

Array.prototype.myFindIndex = function (cb) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this,bindThis = arguments[1] || window
  for (let i = 0; i < _arr.length; i++) {
    const r = cb.call(bindThis,_arr[i],i,_arr)
    if (r) {
      return i
    }
  }
  return -1
}

Array.prototype.myReduce = function (cb,arg1) {
  if (this === null || this === undefined) {
    throw new Error('must be is array')
  }
  let _arr = this
  let i =0
  let origin = arg1
  if (origin === undefined) {
    origin = _arr[i]
    i++
  }
  for (; i < _arr.length; i++) {
    origin = cb(origin,_arr[i],i,_arr)
  }
  return origin
}







var arr = [1,2,3,4,5,6]
var obj = {a:123124}
// arr.myForEach(function (item,i,arr){
//   console.log(item,i,arr)
//   console.log(this.a)
// },obj)

// const arr_map = arr.myMap(function (item,i,arr){
//   return item * 10
// },obj)
// console.log(arr_map)

// const arr_filter = arr.myFilter(function (item,i,arr){
//   return item % 2 === 1
// },obj)
// console.log(arr_filter)

// const arr_every = arr.myEvery(function (item,i,arr){
//   return typeof item === 'number'
// },obj)
// console.log(arr_every)

// const arr_some = arr.mySome(function (item,i,arr){
//   return typeof item === 'string'
// },obj)
// console.log(arr_some)

// const arr_find = arr.myFind(function (item,i,arr){
//   return item % 2 === 1
// },obj)
// console.log(arr_find)

const arr_myReduce = arr.myReduce(function (pre,cur,i,arr){
  return pre + cur
},0)
console.log(arr_myReduce)

